﻿using System;
using System.Diagnostics;
using System.Linq;
using System.Security.Cryptography;
using System.ServiceModel;
using System.Xml;
using Universe.WCF.Behaviors.WcfStreaming;

namespace WcfStreamTests
{
    class TestClient
    {

        public static readonly string Address = "net.pipe://localhost/BioLink/SyncService3";
        
        public static ServiceHost ConfigureService()
        {
            NetNamedPipeBinding binding = new NetNamedPipeBinding();
            binding.HostNameComparisonMode = HostNameComparisonMode.Exact;
            binding.ReaderQuotas = XmlDictionaryReaderQuotas.Max;
            binding.MaxReceivedMessageSize = Int32.MaxValue;
            binding.TransferMode = TransferMode.StreamedResponse;
            ServiceHost sh = new ServiceHost(typeof(MyService));
            sh.AddServiceEndpoint(typeof(IMyService), binding, Address);
            sh.Open();
            Debug.WriteLine("IMyService have published on " + Address);
            return sh;
        }

        public static ChannelFactory<IMyService> ConfigureChannel()
        {
            NetNamedPipeBinding binding = new NetNamedPipeBinding();
            binding.TransferMode = TransferMode.StreamedResponse;
            binding.MaxReceivedMessageSize = Int32.MaxValue;
            binding.MaxBufferSize = 1111111;

            ChannelFactory<IMyService> factory = new ChannelFactory<IMyService>(binding, Address);
            return factory;
        }
        
        public static void RunClient()
        {
            using (var factory = ConfigureChannel())
            {
                factory.Open(TimeSpan.FromMilliseconds(111));
                var proxy = factory.CreateChannel();
                proxy.Ping();
                MD5 md5 = MD5.Create();
                Guid token = Guid.NewGuid();
                var stream = new HashReaderStream(proxy.GetMyStream(token, 9999999, false), md5, 128);
                using(stream)
                {
                    byte[] buffer = new byte[128];
                    long sum = 0;
                    while(true)
                    {
                        int n = stream.Read(buffer, 0, buffer.Length);
                        if (n <= 0)
                            break;

                        sum += n;

                        // throw new Exception();

                        // Console.WriteLine("Readed {0:n0} bytes", sum);
                    }

                    Console.WriteLine("Done. Readed {0} bytes", sum);

                    stream.Close();
                    string md5Value = string.Join("", stream.Hash.Select(x => x.ToString("X2")).ToArray());
                    Console.WriteLine("Client Hash: " + md5Value);
                }
            }
        }
    }
}
